﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Qy.Core;
using Qy.Scenario;
using Qy.Web.Authorize;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Qy.Web.Areas.Api;

[Route("Api/[controller]/[action]")]
[Verify]
public class UploadController : Base
{
    private readonly ConfigService configService;
    private readonly AttmentService _attment;
    private readonly ApplicationContext _applicationContext;
    public UploadController(ApplicationContext applicationContext,ConfigService config, AttmentService attmentService)
    {
        configService = config;
        _attment = attmentService;
        _applicationContext = applicationContext;
    }

    /// <summary>
    /// 上传
    /// </summary>
    /// <param name="uploadDto"></param>
    /// <returns></returns>
    [HttpPost]
    [ActionPermissionFilter(Permission = PermissionKeys.Upload_Upload)]
    public async Task<IActionResult> Upload([FromForm] UploadDto uploadDto)
    {
        IFormFileCollection files = HttpContext.Request.Form.Files;
        UploadRes uploadRes = new();
        if (files.Count < 1)
        {
            uploadRes.Error = "上传文件不存在！";
            return Json(uploadRes);
        }
        IFormFile file = files[0];

        UploadInfo uploadInfo = new()
        {
            Size = file.Length,       //统计文件大小
            FileName = file.FileName,//原始文件名
            SaveDir = uploadDto.SaveDir,//自定义保存目录
            FileExt = Path.GetExtension(file.FileName).ToLower(),//文件后缀
            UpLoadConfig = await configService.GetByUploadAsync()
        };

        uploadRes = uploadDto.Type == "attment" ? AttmentCheck(uploadInfo) : ImgCheck(uploadInfo);
        if (uploadRes.Error != null) return Json(uploadRes);

        string dateDir = DateTime.Now.ToString("yyyyMM");
        var dirPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", uploadInfo.UpLoadConfig.BaseDir, uploadRes.SaveDir, dateDir);
        if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);//如目录不存在，则以当前日期创新目录
        string newFileName = MD5Utility.MD5Encrypt16(uploadInfo.FileName + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff:ffffff")).ToLower(); //获取当前时间微秒 生成MD5
        string saveFilePath = Path.Combine(dirPath, newFileName + uploadInfo.FileExt); //当前上传文件应存放的位置 path.combine 内置跨平台文件系统路径拼接方法
        using var stream = System.IO.File.Create(saveFilePath);
        try
        {
            await file.CopyToAsync(stream);
            uploadRes.Success = true;
            uploadRes.Filename = uploadInfo.FileName;
            uploadRes.Ext = uploadInfo.FileExt;
            uploadRes.Url = "/" + uploadInfo.UpLoadConfig.BaseDir + "/" + uploadRes.SaveDir + "/" + dateDir + "/" + newFileName + uploadInfo.FileExt;

            if (uploadDto.Type == "attment")
            {
                return Json(new { data = uploadRes, status = 1, msg = "成功上传附件", attPkey = await DbPreKeyAsync(uploadInfo, uploadRes.Url) });
            }
            else
            {
                return Json(new { data = uploadRes, status = 1, msg = "上传成功" });
            }
        }
        catch (Exception ex)
        {
            uploadRes.Success = false;
            uploadRes.Error = ex.ToString();
            return Json(uploadRes);
        }
    }

    /// <summary>
    /// 图片检查
    /// </summary>
    /// <returns></returns>
    private static UploadRes ImgCheck(UploadInfo uploadInfo)
    {
        string[] imgageExts = uploadInfo.UpLoadConfig.ImageExt.Split(',');
        int imageSize = uploadInfo.UpLoadConfig.ImageSize * 1024;
        UploadRes uploadRes = new();
        if (((IList)imgageExts).Contains(uploadInfo.FileExt))
        {
            if (!imgageExts.Any(m => m.Equals(uploadInfo.FileExt, StringComparison.OrdinalIgnoreCase)))
            {
                uploadRes.Error = "上传图片类型不合法！";
                return uploadRes;
            }
            if (uploadInfo.Size > imageSize)
            {
                uploadRes.Error = "上传图片超过系统大小限制！";
                return uploadRes;
            }
            uploadRes.SaveDir = uploadInfo.SaveDir ?? uploadInfo.UpLoadConfig.ImageDir;
        }
        else
        {
            uploadRes.Error = "非法上传！";
            return uploadRes;
        }
        return uploadRes;
    }
    /// <summary>
    /// 附件检查
    /// </summary>
    /// <returns></returns>
    private static UploadRes AttmentCheck(UploadInfo uploadInfo)
    {
        UploadRes uploadRes = new();
        string[] fileExts = uploadInfo.UpLoadConfig.FileExt.Split(',');
        int fileSize = uploadInfo.UpLoadConfig.FileSize * 1024;

        if (((IList)fileExts).Contains(uploadInfo.FileExt))
        {
            if (!fileExts.Any(m => m.Equals(uploadInfo.FileExt, StringComparison.OrdinalIgnoreCase)))
            {
                uploadRes.Error = "上传文件类型不合法！";
                return uploadRes;
            }
            if (uploadInfo.Size > fileSize)
            {
                uploadRes.Error = "上传文件超过系统大小限制！";
                return uploadRes;
            }
            uploadRes.SaveDir = uploadInfo.SaveDir ?? uploadInfo.UpLoadConfig.FileDir;
        }
        else
        {
            uploadRes.Error = "非法上传！";
            return uploadRes;
        }
        return uploadRes;
    }
    /// <summary>
    /// 附件上传信息写入数据库
    /// </summary>
    /// <param name="uploadInfo"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    private async Task<int> DbPreKeyAsync(UploadInfo uploadInfo, string url)
    {
        int userId = _applicationContext.ILoginUserInfoMethods.LoginUserId();
        Attment attment = new()
        {
            Filename = uploadInfo.FileName,
            Ext = uploadInfo.FileExt,
            Url = url,
            Size = uploadInfo.Size / 1024,
            Source = uploadInfo.SaveDir,
            Uid = userId,
            Time = DateTime.Now
        };
        return await _attment.InsertReturnIdAsync(attment);
    }

}
